#include <iostream>
#include <string>
#include <math.h>
#include <time.h>
#include <sstream>
using namespace std;
#include "BinaryNode.h"
#include "BinaryTree.h"

//NOTE: This defines the size of trees being generated for testing...if you want more/less, edit this
int const TREE_SIZE = 32;


//Generates a random number but returns it as a string
string randNum()
{
	int ran = rand() % 100;
	string in;
	stringstream inInt;
	inInt << ran;
	return inInt.str();
}

void main() 
{
	//Random seed for creating binary trees
	srand(time(NULL));
	
	cout << "\nTree 1: " << endl;
	BinaryTree* tree1 = new BinaryTree(randNum());
	for(int i = 0; i < TREE_SIZE; i++)
	{
		tree1->insert(randNum());
	}
	cout << tree1->ToTree() << endl;

	system("pause");
	system("cls");
	
	cout << "\nTree 2: " << endl;
	BinaryTree* tree2 = new BinaryTree(randNum());
	for(int i = 0; i < TREE_SIZE; i++)
	{
		tree2->insert(randNum());
	}
	cout << tree2->ToTree() << endl;

	system("pause");
	system("cls");

	cout << "\nTree 3: " << endl;
	BinaryTree* tree3 = new BinaryTree(randNum());
	for(int i = 0; i < TREE_SIZE; i++)
	{
		tree3->insert(randNum());
	}
	cout << tree3->ToTree() << endl;

	system("pause");
	system("cls");

	cout << "\nTesting Copy Constructor \nTree 4 created from Tree 3:" << endl;
	BinaryTree* tree4 = new BinaryTree(*tree3);
	cout << tree3->ToTree() << endl;
	cout << tree4->ToTree() << endl;
	cout << "Checking Tree4's memory location:" << tree4 << endl;
	cout << "Checking Tree3's memory location:" << tree3 << endl;
	cout << "So we know that they are copied, not the same tree!" << endl;

	system("pause");
	system("cls");

	cout << "\nTesting Copy Assignment Operator \nTree4 set equal to Tree 2:" << endl;
	*tree4 = *tree2;
	cout << tree4->ToTree() << endl;
	cout << tree2->ToTree() << endl;
	cout << "Checking Tree4's memory location:" << tree4 << endl;
	cout << "Checking Tree2's memory location:" << tree2 << endl;
	cout << "Again, we know that they are copied, not the same tree!" << endl;

	system("pause");
	system("cls");

	cout << "\nTesting Merge Constructor \nTree5 made from Tree1 and Tree 2" << endl;
	BinaryTree* tree5 = new BinaryTree(tree1,tree2);
	cout << tree5->ToTree() << endl;
	cout << "Dat's a big tree...." << endl;

	system("pause");
	system("cls");

	cout << "\nTesting Delete & Search\nHardCoded Smaller Tree to use values that exist" << endl;
	BinaryTree* tree6 = new BinaryTree("20");
	tree6->insert("30");
	tree6->insert("10");
	tree6->insert("25");
	tree6->insert("35");
	tree6->insert("5");
	tree6->insert("15");
	tree6->insert("1");
	tree6->insert("40");
	cout << "Before Remove:\n" << tree6->ToTree() << endl;
	tree6->removeNode("12");
	cout << "After Remove:\n" << tree6->ToTree() << endl;

	cout << "Search for 55 returns: " << tree6->naivefind("55") << endl;
	cout << "Search for 15 returns: " << tree6->naivefind("15") << endl;

	system("pause");
	system("cls");

	cout << "Time to garbage collect!" << endl;
	delete tree1;
	delete tree2;
	delete tree3;
	delete tree4;
	delete tree5;
	delete tree6;

	system("pause");
}